package service

import (
	"a-common/alog"
	"a-common/config"
	"a-common/domain"
	"a-common/utils/excel"
	"a-system/domain/pojo"
	"encoding/json"
	"fmt"
	"sync"
	"time"

	"github.com/tidwall/gjson"
	"github.com/xuri/excelize/v2"
)

var (
	sysOperlogServiceTemp *SysOperlogService
	sysOperlogServiceOnce sync.Once
)

type SysOperlogService struct{}

func NewSysOperlogService() *SysOperlogService {
	sysOperlogServiceOnce.Do(func() {
		sysOperlogServiceTemp = &SysOperlogService{}
	})
	return sysOperlogServiceTemp
}

// List 列表
func (m *SysOperlogService) List(args *pojo.SysOperlogDto) (vPage domain.PageVo, err error) {
	var timestampNow int64
	var timestampOneMonthAgo int64
	if args.Params.BeginTime != "" && args.Params.EndTime != "" {
		const layout = "2006-01-02 15:04:05"
		loc, err := time.LoadLocation("Asia/Shanghai")
		if err != nil {
			return vPage, err
		}
		begin, err := time.ParseInLocation(layout, args.Params.BeginTime, loc)
		if err != nil {
			return vPage, err
		}
		timestampOneMonthAgo = begin.UnixMicro()
		end, err := time.ParseInLocation(layout, args.Params.EndTime, loc)
		if err != nil {
			return vPage, err
		}
		timestampNow = end.UnixMicro()
	} else {
		// 获取当前时间
		now := time.Now()
		// 获取当前时间的时间戳，单位为微秒
		timestampNow = now.UnixMicro()
		// 获取一个月前的时间
		oneMonthAgo := now.AddDate(0, -1, 0)
		// 获取一个月前的时间戳，单位为微秒
		timestampOneMonthAgo = oneMonthAgo.UnixMicro()
	}

	index := config.Config.Openobserve.Index
	sqlStr := fmt.Sprintf("SELECT * FROM %s WHERE logtype='operlog' ", index)
	if args.Title != "" {
		sqlStr = sqlStr + "AND data_title='" + args.Title + "' "
	}
	sqlStr = sqlStr + "ORDER BY _timestamp DESC"
	query := fmt.Sprintf(`{
		"query": {
			"sql": "%s",
			"start_time": %d,
			"end_time": %d,
			"from": %d,
			"size": %d,
			"track_total_hits": true
		},
		"timeout": 0
	}`, sqlStr, timestampOneMonthAgo, timestampNow, args.PageNum-1, args.PageSize)
	vPage.PageNum = args.PageNum
	vPage.PageSize = args.PageSize

	resByte, err := alog.SendPost("_search", query)
	if err != nil {
		return vPage, err
	}
	if !gjson.ValidBytes(resByte) {
		return vPage, nil
	}

	resStr := string(resByte)
	rows := gjson.Get(resStr, "hits").Raw
	var result []map[string]any
	// 解码JSON到map
	err = json.Unmarshal([]byte(rows), &result)
	if err != nil {
		return vPage, err
	}
	vPage.Rows = result
	vPage.Total = gjson.Get(resStr, "total").Int()
	// vPage.PageNum = int(gjson.Get(resStr, "from").Int())
	// vPage.PageSize = int(gjson.Get(resStr, "size").Int())
	return vPage, nil
}

// Export 导出
func (m *SysOperlogService) Export(args *pojo.SysOperlogDto) (*excelize.File, error) {
	args.PageNum = 1
	args.PageSize = 500
	vPage, err := m.List(args)
	if err != nil {
		return nil, err
	}
	return excel.NormalDynamicExport(vPage.Rows, "Sheet1", "操作日志表", "", true, false, map[string]string{})
}

// Clear 清空
func (m *SysOperlogService) Clear() error {
	return nil
}
